package mutris.client.com;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ConcurrentModificationException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JPanel;

import mutris.client.MutrisGame;
import mutris.client.board.Block;
import mutris.client.board.BlockPoint;
import mutris.client.board.Board;

public class MutrisPanel extends JPanel implements Observer {

	static private final boolean SHOW_GRID = true;
	
	
	private Board board;
	private MutrisGame.GameInfo currentGame;
	
	private AbstractBlockPainter painter;
	
	
	public MutrisPanel(Board  board) {
		this(board, new DefaultBlockPainter());
	}
	
	public MutrisPanel(Board board, AbstractBlockPainter painter) {
		super();
		
		if (null == painter) {
			throw new NullPointerException();
		}
		
		setBoard(board);
		this.painter = painter;
		this.currentGame = null;
		
		setBackground(Color.black);
		
	}
	
	
	public Board getBoard() {
		return board;
	}
	
	
	public void setBoard(Board board) {
		if (null != this.board) {
			this.board.deleteObserver(this);
		}
		
		if (null != board) {
			this.board = board;
			this.board.addObserver(this);
		}
		
		repaint();
	}
	
	
	
	public void paint(Graphics g) {
		super.paint(g);
		
		Graphics2D g2d = (Graphics2D)g;
		
		int cellWidth = 64;
		int cellHeight = 64;
		int boardWidth = board.getWidth();
		int boardHeight = board.getHeight();
		int width = cellWidth * boardWidth;
		int height = cellHeight * boardHeight;
		
		g2d.scale((double)getWidth()/width, (double)getHeight()/height);
		
		if (SHOW_GRID) {
			g2d.setColor(Color.DARK_GRAY);
			for (int x=0; x<width; x+=cellWidth) {
				g2d.drawLine(x, 0, x, height);
			}
			for (int y=0; y<height; y+=cellHeight) {
				g2d.drawLine(0, y, width, y);				
			}
		}
		
		if (board != null) {
			Block block;
			Rectangle rect = new Rectangle(0,0,cellWidth,cellHeight);
			
			boolean complete = false;
			while (!complete) {
				try {
					for (BlockPoint p : board.getPoints()) {
						block = board.getBlock(p);
						rect.setLocation(p.x * cellWidth, p.y * cellHeight);
						painter.paint(p, board, rect, g2d);
					}
					complete = true;
				} catch (ConcurrentModificationException e) {
					/* ignore exception */
				}
			}
			
			if (null != currentGame) {
				if (currentGame.isDead()) {
					//System.out.println("Showing dead state");
					g2d.setColor(new Color(255, 0, 0, 100));
					g2d.fillRect(0, 0, width, height);
				} else if (currentGame.isWinning()) {
					//System.out.println("Showing winning state");
					g2d.setColor(new Color(0, 255, 0, 100));
					g2d.fillRect(0, 0, width, height);				
				}
			}
		}
		
	}

	@Override
	public void update(Observable o, Object arg) {
		if (arg instanceof MutrisGame.GameInfo) {
			this.currentGame = (MutrisGame.GameInfo) arg;
		}
		this.repaint();
	}
	
}
